/***************************************************************************
 *   Copyright (C) 2006 by Marco Bonifazi   *
 *   marcobonifazi@gmail.com   *
 *                                                                         *
 *   Permission is hereby granted, free of charge, to any person obtaining *
 *   a copy of this software and associated documentation files (the       *
 *   "Software"), to deal in the Software without restriction, including   *
 *   without limitation the rights to use, copy, modify, merge, publish,   *
 *   distribute, sublicense, and/or sell copies of the Software, and to    *
 *   permit persons to whom the Software is furnished to do so, subject to *
 *   the following conditions:                                             *
 *                                                                         *
 *   The above copyright notice and this permission notice shall be        *
 *   included in all copies or substantial portions of the Software.       *
 *                                                                         *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       *
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    *
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR     *
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
 *   OTHER DEALINGS IN THE SOFTWARE.                                       *
 ***************************************************************************/
 #include "io_grid.h"
#define X_MAX 60000
#define Y_MAX 60000
#define MAX_ARGS_NUMBER 100

void stats_update(char* file_name, stats* values ){
	FILE* file;

	if ( ( file = fopen( file_name, "a" ) ) == NULL )
		printf( "File %s could not be opened\n", file_name );
	
	else {
		//fprintf(file, "Start area:%ld\tFinal area:%ld\tStart bends:%ld\tFinal bends:%ld\tProcessing time:%g\n",
		fprintf(file, "%i:%ld:%ld:%ld:%ld:%ld:%g\n", values->alghoritm, values->real_nodes_number,
		values->start_area, values->final_area, values->start_bends, values->final_bends, values->elapsed_time);
		printf("\tStats file %s correctly updated\n", file_name);
		fclose(file);
	}
	
}

config* load_config( char* file_name ){
	
	FILE* file;
	config* cfg = NULL;
	
	if ( ( file = fopen( file_name, "r" ) ) == NULL )
		printf( "File %s could not be opened\n", file_name );
		
	else {
		int alghoritm;
		long int arg1, arg2, arg3;
		while ( !feof(file) ){
			fscanf(file, "Alghoritm:%i\n", &alghoritm);
			fscanf(file, "Arg1:%li\n", &arg1);
			fscanf(file, "Arg2:%li\n", &arg2);
			fscanf(file, "Arg3:%li\n", &arg3);
		}
		cfg = malloc(sizeof( config ));
		cfg->alghoritm = alghoritm;
		cfg->args = calloc( MAX_ARGS_NUMBER, sizeof(long int) );
		cfg->args[0] = arg1;
		cfg->args[1] = arg2;
		cfg->args[2] = arg3;
		int i;
		
		for ( i = 3; i < MAX_ARGS_NUMBER; i++)
			cfg->args[i] = 0;
		printf("Config file %s correctly loaded\n", file_name);
		fclose(file);
	}
	return cfg;
};

int scan_grids( char* directory, char*** file_names  ){              
	struct dirent** namelist;
	int n = scandir(directory, &namelist, 0, alphasort);
	int count = 0;
	int str_len;
	
	if (n < 0)
		perror("\t*** Error reading directory %s\n");
		
	else {
		
		int i = 0;
		char* ext;
		count = 0;
		
		for( i = 0; i < n; i ++) {
			str_len = strlen( namelist[i]->d_name );
			
			ext = strstr( namelist[i]->d_name, ".gr" );
			
			if ( ext != NULL && !strcmp(ext, ".gr") )
				count ++;
			
		}
	
		*file_names = calloc( count, sizeof( char* ));
		int c = 0;
		for( i = 0; i < n; i ++) {
			str_len = strlen( namelist[i]->d_name );
			ext = strstr( namelist[i]->d_name, ".gr" );
			
			if ( ext != NULL && !strcmp(ext, ".gr") ){
				(*file_names)[c] = namelist[i]->d_name;
				

				c ++;
				
			}
					
		}

		free(namelist);
		namelist = NULL;
	}
	return count;
}

grid* load_grid(char* file_name){
	FILE* file = NULL;
	grid* new_grid = NULL;
	
	if ( ( file = fopen( file_name, "r" ) ) == NULL )
		printf( "File %s could not be opened\n", file_name );
		
	else {
		int x, y;
		int type;
		int neighs;

		int i, r, n;

		int nodes_number = 0;
		
		/* Scans all file rows and estabilishes nodes number */
		while ( !feof(file) ) {	
			fscanf(file, "%i %i %i %i %i\n", &r, &x, &y, &type, &neighs);
			
			for ( i = 0; i < neighs; i++ )
				fscanf( file, "\t\t%i\n", &n);				

			nodes_number ++;
		}
		
		if ( nodes_number != 0 ){
			rewind(file); /* The file pointer come back at the beginning */
			node** array = calloc(nodes_number, sizeof( node* ) );
			
			/* Scans all file rows and creates the array node (the array can be created in not numeric order */
			while ( !feof(file) ) {
				neighs = 0;
				fscanf(file, "%i %i %i %i %i\n", &r, &x, &y, &type, &neighs);
				x--;
				y--;
				array[r-1] = create_node("", type);	/* The node could be written in different order than one can think looking at node number id */
				
				for ( i = 0; i < neighs; i++ ){
					fscanf( file, "\t\t%i\n", &n);				
	
				}
			}
			rewind(file);
			
			long int x_min, x_max, y_min, y_max;
			
			x_min = X_MAX;
			x_max = 0;
			y_min = Y_MAX;
			y_max = 0;
			node* new_node;
			
			while ( !feof(file) ) {	/* Scans all file rows and creates neighbourhoods */
				fscanf(file, "%i %i %i %i %i\n", &r, &x, &y, &type, &neighs);
				x--;
				y--;
				if ( x < x_min ) x_min = x;
				if ( y < y_min ) y_min = y;
				if ( x > x_max ) x_max = x;
				if ( y > y_max ) y_max = y;
	
				new_node = array[r-1];
				new_node->position[0] = x;
				new_node->position[1] = y;
				
				for ( i = 0; i < neighs; i++ ){
					fscanf( file, "\t\t%i\n", &n);				
	
					if (!is_in_list_nodes( array[n-1]->neighbours, new_node) )
						make_neighbour( array[n-1], new_node);
				}
			}
					
			new_grid = create_2d_empty_grid( (y_max - y_min)+1, (x_max - x_min)+1  );
			node* temp_node;
			
			int node_counter = 0;
			
			/* Puts all nodes in the new grid */

			while (node_counter < nodes_number){
				temp_node = array[node_counter];
				put_node_in_cell(temp_node, new_grid, temp_node->position[0]-x_min, temp_node->position[1]-y_min);
				
				node_counter++;
			}
			free(array);
			array = NULL;
		}	/* End if ( nodes_number != 0 ) */
		
		fclose(file);			
	} /* End else of if ( ( file = fopen( file_name, "r" ) ) == NULL ) */

	return new_grid;
}

int node_number_in_list( list_nodes* nodes, node* node){
	int counter = 0;
	
	while ( nodes != NULL && nodes->node != node){
		counter ++;
		nodes = nodes->next;	
	}
	if ( nodes == NULL ) 
		counter = 0;
	else counter ++;
	
	return counter;
}

int save_grid(grid* gr, char* file_name ){
	int rest;
	int width = gr->dims[0];
	int height = gr->dims[1];
	printf("Width, height %d %d\n", width, height);
	int r, c;
	list_nodes* all_nodes = NULL;
	//list_nodes* temp_nodes;
	/* Scan all not free cells putting them in all_nodes list */
	for ( r = 0; r < height; r++ )

		for ( c = 0; c < width; c++ )
			
			if ( gr->cells[r][c] != NULL ){
				all_nodes = conc_nodes(gr->cells[r][c], all_nodes);
			}
			
	list_nodes* temp_list = all_nodes;
	long int x, y, x_min, x_max, y_min, y_max;
			
	x_min = X_MAX;
	x_max = 0;
	y_min = Y_MAX;
	y_max = 0;
	
	while ( temp_list != NULL ){
		x = temp_list->node->position[0];
		y = temp_list->node->position[1];

		if ( x < x_min ) x_min = x;
		if ( y < y_min ) y_min = y;
		if ( x > x_max ) x_max = x;
		if ( y > y_max ) y_max = y;
		
		temp_list = temp_list->next;	
	}
	
	FILE * file;
	
	if ( ( file = fopen( file_name, "w" ) ) == NULL )
		printf( "File %s could not be opened\n", file_name );
		
	else {
		/*fprintf( file, "Height:%d\nWidth:%d\nAlghoritm:%d\nArg1:%d\nArg2:%d\nArg3:%d\n\nArea:%d\nLength:%d\nNodes Number:%d\nArcs Number:%d\nBends Number:%d\nElapsed Time:%f\n\n\n", gr->dims[0], gr->dims[1],  gr->alghoritm, gr->args[0], gr->args[1], gr->args[2], gr->area, gr->length, counter-1, gr->arcs_number, gr->bends_number,gr->elapsed_time );
		*/
		int count = 1;
		node* n;
		temp_list = all_nodes;
		list_nodes* neighs;
		
		while ( temp_list != NULL ){
			n = temp_list->node;
			x = n->position[0];
			y = n->position[1];
			fprintf( file, "%d %ld %ld %d %d\n", count, x-x_min, y-y_min, n->type,  neighbours_number(n) );
			
			neighs = NULL;
			neighs = n->neighbours;
			
			while ( neighs != NULL ){
				fprintf( file, "\t\t%d\n", node_number_in_list(all_nodes, neighs->node));
				neighs = neighs->next;
			}
			count ++;
			temp_list = temp_list->next;
		}
		
		
		printf("File %s saved\n", file_name);
		/*printf("Starting node:%i\n", gr->starting_node->number);*/
		rest = 1;
		fclose( file );
	}
	
	return rest;
}
